<template>
	<view class="audio-container">
		<!-- #ifdef H5 -->
		<video v-if="audioList[audioActiveIndex]" id="audio" style="display: none;" :autoplay="autoplay?autoplay:''"
			:src="audioList[audioActiveIndex].fileUrl" @error="onError" @timeupdate="setPlayData"
			@loadedmetadata="onCanplay" @play="onPlay" @pause="onPause" @ended="onEnded">
		</video>
		<!-- #endif -->
		<!-- 封面图区域 -->
		<view class="audio-coverImage" v-if="showCoverImage">
			<image :src="currentCoverImage"></image>
		</view>
		<!-- 调速拉条区 -->
		<view class="audio-progress">
			<!-- 后退15秒 -->
			<image src="@/uni_modules/DHS-Audio/static/get-back.svg" :class="prevDisabled && 'halfOpcity'"
				@click="onSeek(-15)"></image>
			<!-- 进度条 -->
			<view class="audio-bar">
				<slider class="audio-slider" :value="currentTime" :min="0" :activeColor="customColor"
					:backgroundColor="backgroundColor" :block-size="blockSize" :max="duration" @change="sliderChange"
					@changing="sliderChanging" :block-color="customColor" block-size="18" />
			</view>
			<!-- 快进15秒 -->
			<image src="@/uni_modules/DHS-Audio/static/fast-forward.svg" :class="nextDisabled && 'halfOpcity'"
				@click="onSeek(15)"></image>
		</view>
		<!-- 显示时间进度区 -->
		<view class="bar-tips">
			<text>{{minTimeFmt(currentTime)}}</text>
			<text>{{minTimeFmt(duration)}}</text>
		</view>
		<!-- 按钮区 -->
		<view class="audio-btn">
			<!-- 列表按钮 -->
			<template v-if="showAudioListIcon">
				<image src="@/uni_modules/DHS-Audio/static/play-list.svg" @click="onOpenList"></image>
			</template>
			<template v-else>
				<image></image>
			</template>
			<view class="play-box">
				<!-- 上一首 -->
				<image src="@/uni_modules/DHS-Audio/static/last-episode.svg" :style="{'opacity':showLeftBtnOpacity}"
					@click="onSwitchAudio(audioActiveIndex - 1)" @touchstart="()=>{}"></image>
				<!-- 播放/暂停 -->
				<view class="play-btn" :style="{backgroundColor:isPaused? customColor:'#475266'}" @click="onPlayPause">
					<view v-show="isPaused" :class="isPaused ? 'play-button':'stop-button'"></view>
				</view>
				<!-- 下一首 -->
				<image src="@/uni_modules/DHS-Audio/static/next-set.svg" :style="{'opacity':showRightBtnOpacity}"
					@click="onSwitchAudio(audioActiveIndex + 1)"></image>
			</view>
			<!-- 倍速切换 -->
			<view class="triple-speed" v-if="showAudioSpeedIcon">
				<image src="@/uni_modules/DHS-Audio/static/triple-speed.svg" @click="onSpeed"></image>
				<text class="speed-text" @click="onSpeed">{{speed}}</text>
			</view>
			<template v-else>
				<image></image>
			</template>


		</view>
	</view>

</template>
<script setup>
	import {
		ref,
		computed,
		onMounted,
		onUnmounted,
		nextTick
	} from 'vue'
	import defaultCoverImage from '@/uni_modules/DHS-Audio/static/default-cover.jpeg'
	let innerAudioContext = null;
	const emits = defineEmits(['onAudioChange', 'onPlayProgress', 'onAudioEnd', 'onOpenAudioList'])
	const props = defineProps({
		/**
		 * audioData 播放列表
		 * @property {String} title 播放名称
		 * @property {String} fileUrl 播放链接
		 * */
		audioData: {
			type: Array,
			default: () => {
				return []
			}
		},
		customColor: {
			type: String,
			default: '#475266'
		},
		// 进度条背景色
		backgroundColor: {
			type: String,
			default: '#e9e9e9'
		},
		// 滑块大小
		blockSize: {
			type: Number,
			default: 24
		},
		// 当前播放的位置索引
		activeIndex: {
			type: Number,
			default: -1
		},
		// 是否显示封面图
		showCoverImage: {
			type: Boolean,
			default: true
		},
		// 是否显示播放列表
		showAudioListIcon: {
			type: Boolean,
			default: true
		},
		// 是否显示播放倍速
		showAudioSpeedIcon: {
			type: Boolean,
			default: false
		},
		// 是否自动播放
		autoplay: {
			type: Boolean,
			default: false
		},
		// 是否循环播放
		loopPlay: {
			type: Boolean,
			default: false
		},
		// 播放速度 只能是 0.5/0.8/1.0/1.25/1.5/2.0,循环
		seekList: {
			type: Array,
			default: () => {
				return [0.5, 0.8, 1.0, 1.25, 1.5, 2.0]
			}
		}
	})
	const audioActiveIndex = ref(0) //当前播放索引
	const audioList = ref([])
	const isPaused = ref(true) //是否暂停中
	const duration = ref(0) //音频时长
	const currentTime = ref(0) //当前时长
	const speed = ref(1) //倍速
	const isSlidering = ref(false) //是否移动中
	const isEndAcudio = ref(false) //最后一个音频结束

	const prevDisabled = computed(() => {
		return !audioList.value.length || currentTime.value === 0
	})

	const nextDisabled = computed(() => {
		return !audioList.value.length || currentTime.value === duration.value
	})
	const currentCoverImage = computed(() => {
		return audioList.value[audioActiveIndex.value]?.coverImage || defaultCoverImage
	});

	const showLeftBtnOpacity = computed(() => {
		return (audioActiveIndex.value === 0 || !audioList.value.length) ? 0.5 : 1
	})

	const showRightBtnOpacity = computed(() => {
		return (!audioList.value.length || audioActiveIndex.value + 1 === audioList.value.length) ? 0.5 : 1
	})
	// 格式化时间
	const minTimeFmt = (val) => {
		let minute = parseInt(val / 60);
		let seconds = Math.ceil(val % 60)
		return `${minute>=10?minute:'0'+minute}:${seconds>=10?seconds:'0'+seconds}`
	}
	const startPlay = () => {
		// #ifdef H5
		innerAudioContext = uni.createVideoContext('DHS-audio');
		// #endif
		// #ifdef MP-WEIXIN || MP-ALIPAY || MP-LARK
		innerAudioContext = uni.createInnerAudioContext();
		// #endif
		// #ifdef APP-PLUS
		innerAudioContext = uni.getBackgroundAudioManager();
		// #endif
		/*
		play		播放（H5端部分浏览器需在用户交互时进行）	
		pause		暂停	
		stop		停止	
		seek	position	跳转到指定位置，单位 s	
		destroy		销毁当前实例
		*/
		innerAudioContext.startTime = 0; //开始播放的位置（单位：s）
		setAudioInfo(false);
		// #ifdef H5
		innerAudioContext.playbackRate(1.0);
		// #endif
		// #ifndef H5
		innerAudioContext.playbackRate = speed.value; //放的倍率。可取值：0.5/0.8/1.0/1.25/1.5/2.0
		// 音频播放事件
		innerAudioContext.onPlay(() => {
			onPlay();
		});
		// 音频暂停事件
		innerAudioContext.onPause(() => {
			onPause();
		});
		// 音频进入可以播放状态，但不保证后面可以流畅播放
		innerAudioContext.onCanplay(() => {
			onCanplay();

		});
		// 音频自然播放结束事件
		innerAudioContext.onEnded(() => {
			onEnded();
		});
		// 音频播放错误事件
		innerAudioContext.onError((res) => {
			onError(res)
		});
		// 音频播放进度更新事件
		innerAudioContext.onTimeUpdate(() => {
			setPlayData();
		});
		// #endif
		// #ifdef APP-PLUS
		// 用户在系统音乐播放面板点击上一曲事件（iOS only）
		innerAudioContext.onPrev(() => {
			// 切换到上一个音频
			onSwitchAudio(audioActiveIndex.value - 1);
			// console.log("用户在系统音乐播放面板点击下一曲事件（iOS only）");
		});
		// 用户在系统音乐播放面板点击下一曲事件（iOS only）
		innerAudioContext.onNext(() => {
			// 切换到下一个音频
			onSwitchAudio(audioActiveIndex.value + 1);
			// console.log("用户在系统音乐播放面板点击下一曲事件（iOS only）");
		});
		// #endif
	}
	// 暂停播放切换
	const onPlayPause = () => {
		if (isPaused.value) {
			if (isEndAcudio.value) {
				innerAudioContext.title = audioList.value[audioActiveIndex.value]?.title;
				innerAudioContext.coverImgUrl = audioList.value[audioActiveIndex.value]?.image;
				innerAudioContext.src = encodeURI(audioList.value[audioActiveIndex.value]?.fileUrl).replace(/\+/g,
					"%2B"); //音频的数据链接，用于直接播放。
			}
			innerAudioContext.play()
			isPaused.value = false;
		} else {
			innerAudioContext.pause()
			isPaused.value = true;
		}
	};
	// 切换音频
	const onSwitchAudio = (index) => {
		if (index < 0 || index >= audioList.value.length) return;
		audioActiveIndex.value = index;
		setAudioInfo(props.autoplay); // 使用props设置
		emits('onAudioChange', audioList.value[audioActiveIndex.value], index)
	};
	// 调整播放倍速 需调整
	const onSpeed = () => {
		let speedIndex = props.seekList.findIndex(x => x === speed.value)
		if (!speedIndex && speedIndex !== 0) {
			speed.value = 1
		} else {
			console.log(speedIndex + 1);
			if (speedIndex + 1 > props.seekList.length - 1) {
				speed.value = props.seekList[0]
			} else {
				const current = props.seekList[speedIndex + 1]
				console.log(current)
				// #ifdef H5
				innerAudioContext.playbackRate(current);
				// #endif
				// #ifndef H5
				innerAudioContext.playbackRate = current;
				// #endif
				speed.value = current
			}
		}
	};
	// 调整播放位置
	const onSeek = (num) => {
		if (!currentTime.value || (num < 0 && prevDisabled.value) || (num > 0 && nextDisabled.value)) return;
		let seekNum = num + currentTime.value;
		isSlidering.value = true;
		if (seekNum < 0) {
			// 调整后时间小于0
			currentTime.value = 0;
			innerAudioContext.seek(0)
		} else if (seekNum > duration.value) {
			// 调整后时间大于总时长
			currentTime.value = duration.value;
			innerAudioContext.seek(duration.value)
		} else {
			currentTime.value = seekNum;
			innerAudioContext.seek(seekNum)
		}
		isSlidering.value = false;
	};
	// 滑块滚动到的位置
	const sliderChange = (e) => {
		isSlidering.value = false;
		currentTime.value = e.detail.value;
		innerAudioContext.seek(e.detail.value);
	};
	// 滑块滚动到的位置 实时
	const sliderChanging = (e) => {
		isSlidering.value = true;
		currentTime.value = e.detail.value;
	};
	// 设置以及转换信息
	const setPlayData = (event) => {
		// #ifndef H5
		if (isSlidering.value) return;
		if (!innerAudioContext.duration && !innerAudioContext.currentTime) return;
		duration.value = innerAudioContext.duration || 0;
		currentTime.value = innerAudioContext.currentTime || 0;
		emits('onPlayProgress', currentTime.value, duration.value)
		// #endif
		// #ifdef H5
		if (isSlidering.value) return;
		duration.value = event.detail.duration || 0;
		currentTime.value = event.detail.currentTime || 0;
		emits('onPlayProgress', currentTime.value, duration.value)
		// #endif
	};
	// 设置播放
	const setAudioInfo = (isAutoplay) => {
		if (innerAudioContext && audioActiveIndex.value > -1 && audioList.value[audioActiveIndex.value]?.fileUrl) {
			innerAudioContext.title = audioList.value[audioActiveIndex.value]
				?.title; //音频标题，用于做原生音频播放器音频标题。原生音频播放器中的分享功能，分享出去的卡片标题，也将使用该值。
			innerAudioContext.coverImgUrl = audioList.value[audioActiveIndex.value]
				?.image; //封面图url，用于做原生音频播放器背景图。原生音频播放器中的分享功能，分享出去的卡片配图及背景也将使用该图。
			innerAudioContext.src = encodeURI(audioList.value[audioActiveIndex.value]?.fileUrl).replace(/\+/g,
				"%2B"); //音频的数据链接，用于直接播放。
			// #ifndef H5 || MP-ALIPAY || MP-LARK
			// 播放本地文件
			const currentAudio = audioList.value[audioActiveIndex.value];
			if (currentAudio && typeof currentAudio.fileUrl === 'string' && currentAudio.fileUrl.startsWith('/')) {
				innerAudioContext.src = currentAudio.fileUrl;
			}
			// #endif
			innerAudioContext.epname = audioList.value[audioActiveIndex.value]
				?.epname; //专辑名，原生音频播放器中的分享功能，分享出去的卡片简介，也将使用该值。
			innerAudioContext.singer = audioList.value[audioActiveIndex.value]
				?.singer; //歌手名，原生音频播放器中的分享功能，分享出去的卡片简介，也将使用该值。
			innerAudioContext.webUrl = audioList.value[audioActiveIndex.value]
				?.webUrl; //页面链接，原生音频播放器中的分享功能，分享出去的卡片简介，也将使用该值。
			if (isAutoplay || props.autoplay) {
				innerAudioContext.play();
			} else {

				innerAudioContext.pause();

			}
		}
		if (!audioList.value[audioActiveIndex.value]?.fileUrl) {
			duration.value = 0;
			currentTime.value = 0;
			isPaused.value = true;
			innerAudioContext.pause();
		}
	};
	const onOpenList = () => {
		emits('onOpenAudioList')
	}
	// 播放事件
	const onPlay = () => {
		// console.log('音频播放事件');
		isEndAcudio.value = false;
		isSlidering.value = false;
		isPaused.value = false;
	};
	// 暂停事件
	const onPause = () => {
		// console.log("音频暂停事件");
		isPaused.value = true;
	};
	// 播放结束事件
	const onEnded = () => {
		// 是否最后一个音频
		if (audioActiveIndex.value + 1 >= audioList.value.length) {
			// console.log("最后一个音频")
			// 循环播放
			if (props.loopPlay) {
				onSwitchAudio(0);
				return;
			}
			currentTime.value = 0;
			isPaused.value = true;
			isEndAcudio.value = true;
			emits('onAudioEnd')
			return;
		}
		// 切换到下一个音频
		onSwitchAudio(audioActiveIndex.value + 1);
		// console.log("音频自然播放结束事件");
	};
	// 音频进入可以播放状态
	const onCanplay = (event) => {
		// console.log('音频进入可以播放状态，但不保证后面可以流畅播放');
		// console.log("音频时长：", innerAudioContext.duration)
		isSlidering.value = false;
		setPlayData(event);
		if (!props.autoplay && !isEndAcudio.value) {
			innerAudioContext.pause();
			isPaused.value = true;
		}
	};
	// 播放失败
	const onError = (res) => {
		// console.log("音频播放错误事件", res);
		duration.value = 0;
		currentTime.value = 0;
		isPaused.value = true;
		innerAudioContext.pause();
	}

	onMounted(async () => {
		await nextTick()
		audioActiveIndex.value = props.activeIndex
		audioList.value = props.audioData
		startPlay()
	})
	onUnmounted(() => {
		// #ifdef MP-ALIPAY || MP-LARK
		innerAudioContext.destroy();
		// #endif
		// #ifdef H5
		innerAudioContext.pause();
		// #endif
	})
</script>
<style scoped lang="scss">
	.audio-container {
		width: 100vw;
		padding: 0 64rpx;
		box-sizing: border-box;

		.halfOpcity {
			opacity: 0.5;
		}

		.audio-coverImage {
			image {
				display: block;
				width: 100%;
				border-radius: 20rpx;
			}

			margin-bottom: 20rpx;
		}


		.audio-progress {
			display: flex;
			align-items: center;
			justify-content: space-between;

			image {
				width: 48rpx;
				height: 48rpx;
			}

			.audio-bar {
				flex: 1;
				padding: 0 26rpx;
				box-sizing: border-box;

				.audio-slider {
					margin: 0 !important;
				}
			}
		}

		.bar-tips {
			display: flex;
			align-items: center;
			justify-content: space-between;
			padding: 0 74rpx;
			margin-bottom: 32rpx;
			color: #B8BECC;
			font-size: 24rpx;
			line-height: 10rpx;
		}

		.audio-btn {
			position: relative;
			display: flex;
			align-items: center;
			justify-content: space-between;

			image {
				width: 48rpx;
				height: 48rpx;
			}

			.play-box {
				display: flex;
				align-items: center;
			}

			.play-btn {
				width: 96rpx;
				height: 96rpx;
				display: flex;
				align-items: center;
				justify-content: center;
				margin: 0 64rpx;
				background: #475266;
				border-radius: 50%;

				.play-button {
					width: 0;
					height: 0;
					margin-left: 8rpx;
					border-top: 20rpx solid transparent;
					/* 上边框透明 */
					border-bottom: 20rpx solid transparent;
					/* 下边框透明 */
					border-left: 30rpx solid #fff;
					/* 左边框设置三角形的高度和颜色 */
					border-radius: 6rpx;
				}

				.stop-button {
					display: inline-block;
					width: 80rpx;
					height: 30rpx;
					position: relative;
					background-color: transparent;
					/* Optional: makes the button background transparent */
					border: none;
					/* Optional: removes any default border from the button */
				}

				.stop-button::before,
				.stop-button::after {
					content: '';
					position: absolute;
					top: 0;
					width: 10rpx;
					height: 100%;
					background-color: #fff;
					left: calc(50% - 10rpx);
					transform: translateX(-50%);
					border-radius: 10rpx;
				}

				.stop-button::after {
					left: calc(50% + 10rpx);
					/* Adjust the spacing between the lines */
				}
			}

			.play-list-text {
				position: absolute;
				bottom: 0;
				left: -14rpx;
				color: #475266;
				font-size: 20rpx;
			}

			.triple-speed {
				width: 84rpx;
				height: 84rpx;
				position: relative;
				display: flex;
				align-items: center;
				justify-content: center;

				image {
					position: absolute;
					left: 0;
					top: 0;
					display: block;
					width: 100%;
					height: 100%;
				}

				.speed-text {
					margin: auto;
					color: #475266;
					font-size: 24rpx;
					font-weight: 600;
				}
			}

		}
	}
</style>